#include "lrcwidget.h"
#include "ui_lrcwidget.h"
#include "searchmanager.h"
#include <QDebug>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
LrcWidget::LrcWidget(QWidget *parent)
    : QWidget(parent)
    , _manager(new QNetworkAccessManager(this))
    , ui(new Ui::LrcWidget)
{
    ui->setupUi(this);
}

LrcWidget::~LrcWidget() { delete ui; }

void LrcWidget::updateCurUrl(const QUrl &url)
{
    qDebug() << "_currentUrl: " << _currentUrl << " ,  url: " << url;
    if(_currentUrl == url) return;
    _currentUrl = url;
    _lyric.clear();

    qint64 id = SongManager::instance()->getSongItem(url).wangyiyun_id;
    qDebug() << "当前播放歌曲的网易云id: " << id;
    if (id == 0){ // 本地, 先搜索单曲, 根据 id 再搜索歌词
        const SongItem& song = SongManager::instance()->getSongItem(url);
        QString search_text = song.name + ' ' + song.artist;
        qDebug() << "查找本地音乐" << song.name << "-" << song.artist << "的网易云id";
        SearchManager::getInstance().searchSongs(
            search_text,
            bind(&LrcWidget::on_songsReply_finished, this, url, std::placeholders::_1)
        );
    }
    else SearchManager::getInstance().searchLrc(
        id,
        bind(&LrcWidget::on_lrcReply_finished, this, url, std::placeholders::_1)
    );
}

void LrcWidget::updateCurDuration(qint64 duration)
{
    int index = getIndexOf(duration);
    ui->label_1->setText(getText(index - 2));
    ui->label_2->setText(getText(index - 1));
    ui->label_3->setText(getText(index - 0));
    ui->label_4->setText(getText(index + 1));
    ui->label_5->setText(getText(index + 2));
    ui->label_6->setText(getText(index + 3));
    ui->label_7->setText(getText(index + 4));
    ui->label_8->setText(getText(index + 5));
    ui->label_9->setText(getText(index + 6));
}

void LrcWidget::on_songsReply_finished(QUrl url, QByteArray data)
{
    auto songs = QJsonDocument::fromJson(data).object().value("result").toObject().value("songs").toArray();
    if(songs.size() == 0)
    {
        qDebug() << "未找到本地音乐" << url << "的网易云id";
        return;
    }
    qint64 id = songs[0].toObject().value("id").toVariant().toLongLong();
    if(id)
    {
        qDebug() << "找到了本地音乐" << url << "的网易云id:" << id;
        const SongItem& song = SongManager::instance()->getSongItem(url);
        SongItem updatedSong = song;
        updatedSong.wangyiyun_url = "http://music.163.com/song/media/outer/url?id=" + QString::number(id) + ".mp3";
        updatedSong.wangyiyun_id = id;
        SongManager::instance()->addSongItem(updatedSong);
        SearchManager::getInstance().searchLrc(
            id,
            bind(&LrcWidget::on_lrcReply_finished, this, url, std::placeholders::_1)
        );
    }
    else
        qDebug() << "未找到本地音乐" << url << "的网易云id";
}

void LrcWidget::on_lrcReply_finished(QUrl url, QByteArray data)
{
    if(url != this->_currentUrl)
    {
        qDebug() << url << "的歌词搜索结果忽略, 当前应显示 " << this->_currentUrl;
        return;
    }
    QString ret = QJsonDocument::fromJson(data).object().value("lrc").toObject().value("lyric").toString();
    if(ret.size() == 0)
    {
        _lyric.push_back({0, "未找到歌词"});
        return;
    }
    QStringList lines = ret.split("\n", QString::SkipEmptyParts); // 按换行符分割成单行
    qDebug() << "--------------------------------开始提取歌词--------------------------------";
    for(auto line : lines) // 对每行提取时间 + 内容
    {
        int min, sec, ms;
        sscanf(line.toStdString().c_str(), "[%d:%d.%d]", &min, &sec, &ms);
        line.remove(0, line.lastIndexOf(']') + 1);
        if(line.isEmpty()) continue;
        qDebug() << min << sec << ms << line;
        qint64 duration = min * 60 * 1000 + sec * 1000 + ms;
        _lyric.push_back({duration, line});
    }
    qDebug() << "--------------------------------提取歌词结束--------------------------------";
}

int LrcWidget::getIndexOf(qint64 duration)
{
    int ret = -1;
    // TODO: 改成二分
    while(ret + 1 < _lyric.size() && duration >= _lyric[ret + 1].time){
        ret++;
    }
    return ret;
}

QString LrcWidget::getText(int index)
{
    if(index < 0 || index >= _lyric.size()) return "";
    else return _lyric[index].text;
}
